package cn.changeforyou.analyzer.xmlparse.mybatis;

import cn.changeforyou.analyzer.ParseException;
import cn.changeforyou.analyzer.combine.orm.XmlCodeType;
import cn.changeforyou.analyzer.xmlparse.mybatis.model.MybatisXmlContent;
import cn.changeforyou.utils.string.StringUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
import org.dom4j.tree.DefaultAttribute;

public class MybatisXmlParse {
	
	private MybatisXmlContent xmlEntity;
	private String tableName;
	
	public MybatisXmlParse(String tableName) {
		xmlEntity = new MybatisXmlContent();
		this.tableName = tableName;
	}
	
	public MybatisXmlContent getMybatisXmlEntity(String path) {
		if (StringUtils.isEmpty(path)) {
			throw new ParseException("路径不对");
		}
		File file = new File(path);
		if (!file.exists()) {
			return null;
		}
		SAXReader saxReader = new SAXReader();
		org.dom4j.Document doc = null;
		FileInputStream fileInputStream = null;
		try {
			fileInputStream = new FileInputStream(file);
			doc = saxReader.read(fileInputStream);
		} catch (DocumentException e) {
			e.printStackTrace();
			throw new ParseException("解析xml失败");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
		xmlEntity.setRoot(doc.getRootElement());
		xmlEntity.setNamespace(getNamespace(doc));
		xmlEntity.setFile(file);
		xmlEntity.setTableName(tableName);
		getXmlLabels(doc);
		try {
			fileInputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return xmlEntity;
	}
	
	
	/**
	 * 解析namespace
	 *
	 * @param doc
	 * @return
	 */
	private String getNamespace(Document doc) {
		XPath xPath = DocumentHelper.createXPath("/mapper/@namespace");
		List<Node> nodes = xPath.selectNodes(doc);
		for (Node node : nodes) {
			if (node instanceof DefaultAttribute) {
				DefaultAttribute attribute = (DefaultAttribute) node;
				return attribute.getStringValue();
			}
		}
		return null;
	}
	
	/**
	 * 解析ResultMap
	 *
	 * @param doc
	 * @return
	 */
	private void getXmlLabels(Document doc) {
		XmlCodeType[] codeTypes = XmlCodeType.values();
		for (XmlCodeType codeType : codeTypes) {
			xmlEntity.addAll(codeType.getReaderWriter().read(doc));
		}
	}
}
